package game.network
{
	import engine.core.*;
	import engine.network.*;
	
	import game.*;
	import game.messages.*;
	import game.messages.login.*;
	
	public class RxTransactionServer
	{
		private var m_socket:RxNetMessageSocket;
		private var m_netMessageDistributor:RxNetMessageDistributor;
		private var m_connected:Boolean;
		private var m_loggedIn:Boolean;
		private var m_loginMsg:RxLogin_LoginPlayerMessage;
		private var m_loginStatusChangedCallback:Function;
		private var m_url:String;
		private var m_port:int;
		private var m_hasCommunityPermission:Boolean;
		private var m_hasQAPermission:Boolean;
		public static const STATUS_LOGOUT_DISCONNECTED:int = 250;
		private static var s_instance:RxTransactionServer;
		
		public function RxTransactionServer(url:String, port:int, distri:RxNetMessageDistributor)
		{
			this.m_socket = new RxNetMessageSocket();
			this.m_loginMsg = new RxLogin_LoginPlayerMessage();
			s_instance = this;
			this.m_netMessageDistributor = distri;
			this.m_socket.SetMessageCallback(this.OnMessage);
			this.m_socket.SetConnectCallback(this.OnConnect);
			this.m_socket.SetDisconnectCallback(this.OnDisconnect);
			this.m_connected = false;
			this.SetServerAddress(url, port);
		}
		
		public function SetServerAddress(url:String, port:int) : void
		{
			this.m_url = url;
			this.m_port = port;
		}
		
		private function OnMessage(netMessage:RxNetMessageBase) : void
		{
			var loginConnectMessage:RxLogin_ConnectStatusMessage = null;
			var loginMessage:RxLogin_LoginStatusMessage = null;
			switch(netMessage.GetId())
			{
				case RxLogin_ConnectStatusMessage.messageId:
				{
					loginConnectMessage = RxLogin_ConnectStatusMessage(netMessage);
					this.HandleStatusMessage(loginConnectMessage.statusCode, 0, loginConnectMessage.statusString);
					break;
				}
				case RxLogin_LoginStatusMessage.messageId:
				{
					loginMessage = RxLogin_LoginStatusMessage(netMessage);
					this.HandleStatusMessage(loginMessage.statusCode, loginMessage.flags, loginMessage.statusString);
					if (loginMessage.flags & RxLogin_LoginStatusMessage.FLAG_PERMISSION_COMMUNITY)
					{
						this.m_hasCommunityPermission = true;
					}
					if (loginMessage.flags & RxLogin_LoginStatusMessage.FLAG_PERMISSION_QA)
					{
						this.m_hasQAPermission = true;
					}
					break;
				}
				default:
				{
					this.m_netMessageDistributor.Distribute(netMessage);
					break;
				}
			}
		}
		
		private function HandleStatusMessage(param1:int, param2:uint, param3:String) : void
		{
			this.m_loggedIn = param1 == RxLogin_LoginStatusMessage.STATUS_LOGIN_SUCCEEDED;
			if (this.m_loggedIn)
			{
				RxLog.Info("login succeeded");
			}
			else
			{
				RxLog.Info("login failed: \"" + param3 + "\"");
			}
			this.LoginStatus(param1, param2, param3);
		}
		
		private function OnConnect() : void
		{
			RxLog.Info("Connected to " + this.m_url + ":" + this.m_port);
			this.m_connected = true;
			var connectMessage:RxLogin_ConnectMessage = new RxLogin_ConnectMessage();
			connectMessage.versionFingerprint = RxMaster.GetBuildVersion() + "." + RxRegisterAllMessages.versionFingerprint;
			connectMessage.versionDate = RxRegisterAllMessages.versionDate;
			this.m_socket.SendMessage(connectMessage);
			this.m_socket.SendMessage(this.m_loginMsg);
			this.m_socket.Flush();
		}
		
		private function OnDisconnect() : Boolean
		{
			RxLog.Info("Disconnected from " + this.m_url + ":" + this.m_port);
			this.m_connected = false;
			this.LoginStatus(STATUS_LOGOUT_DISCONNECTED, 0, "unexpectedly disconnected from server");
			return false;
		}
		
		private function LoginStatus(param1:int, param2:uint, param3:String) : void
		{
			if (this.m_loginStatusChangedCallback != null)
			{
				this.m_loginStatusChangedCallback(param1, param2, param3);
			}
		}
		
		public function Disconnect() : void
		{
			RxLog.Trace("RxTransactionServer.Disconnect()");
			this.m_socket.Disconnect();
			this.m_loggedIn = false;
			this.m_connected = false;
		}
		
		public function hasQAPermission() : Boolean
		{
			return m_hasQAPermission;
		}
		
		public function AddListener(key:uint, fun:Function) : void
		{
			this.m_netMessageDistributor.AddListener(key, fun);
		}
		
		public static function get instance() : RxTransactionServer
		{
			return s_instance;
		}
		
		public function GetURL() : String
		{
			return this.m_url;
		}
		
		public function GetPort() : int
		{
			return this.m_port;
		}
		
		public function SetLoginStatusChangedCallback(param1:Function) : void
		{
			this.m_loginStatusChangedCallback = param1;
		}
		
		public function SendMessage(param1:RxNetMessageBase) : void
		{
			this.m_socket.SendMessage(param1);
		}
		
		public function Update(param1:Number) : void
		{
			RxNetIDManager.instance.Update(this.m_socket);
			this.m_socket.Flush();
		}
		
		public function RemoveListener(param1:uint, param2:Function) : void
		{
			this.m_netMessageDistributor.RemoveListener(param1, param2);
		}
		
		public function Open(param1:String, param2:String) : void
		{
			RxLog.Info(" Connecting to " + this.m_url + " : " + this.m_port + " as " + param1 + " : " + param2 + " ", true);
			var _loc_3:* = new RxLogin_ClientInfo();
			var _loc_4:* = RxSystemInfo.Collect(RxStage.stage);
			_loc_3.device = "FlashPlayer";
			_loc_3.os = _loc_4.os + (_loc_4.os64Bit ? (" (64 bit)") : (""));
			_loc_3.systemLanguage = _loc_4.language;
			_loc_3.browserName = _loc_4.browserType;
			_loc_3.browserVersion = _loc_4.browserVersion;
			_loc_3.socialNetwork = param1;
			_loc_3.socialNetworkUserId = param2;
			_loc_3.graphicsDriverType = _loc_4.graphicsDriver;
			_loc_3.flashVersion = _loc_4.playerVersion;
			_loc_3.flashType = _loc_4.playerConfiguration + " " + _loc_4.playerType;
			_loc_3.screenWidth = _loc_4.screenResolutionX;
			_loc_3.screenHeight = _loc_4.screenResolutionY;
			this.m_loginMsg.network = param1;
			this.m_loginMsg.userName = param2;
			if (_loc_4.graphicsHardwareAcceleration)
			{
				this.m_loginMsg.flags = this.m_loginMsg.flags | RxLogin_LoginPlayerMessage.FLAG_HARDWARE_GRAPHICS_ACCELERATION;
			}
			this.m_loginMsg.clientInfo.length = 0;
			this.m_loginMsg.clientInfo.push(_loc_3);
			this.m_socket.Connect(this.m_url, this.m_port);
		}
		
		public function IsConnected() : Boolean
		{
			return this.m_connected;
		}
		
		public function IsConnecting() : Boolean
		{
			return this.m_socket.Connecting();
		}
		
		public function IsLoggedIn() : Boolean
		{
			return this.m_connected && this.m_loggedIn;
		}
		
		public function GetLoginUserId() : String
		{
			return this.m_loginMsg.userName;
		}
		
		public function GetLoginChannel() : String
		{
			return this.m_loginMsg.network;
		}
	}
}